Skip to content

Intel iGPU passthrough support for KVM/Xen with UEFI#5686

Draft
rucoder wants to merge 4 commits intolf-edge:masterfrom
rucoder:rucoder/igpu-support
Draft

Intel iGPU passthrough support for KVM/Xen with UEFI#5686
rucoder wants to merge 4 commits intolf-edge:masterfrom
rucoder:rucoder/igpu-support

Conversation

@rucoder
Copy link
Copy Markdown
Contributor

@rucoder rucoder commented Mar 18, 2026

Description

Add Intel integrated GPU (iGPU) passthrough support for KVM guests running with UEFI (OVMF). Enables Windows and Linux VMs to use the Intel iGPU via VFIO passthrough with full display output (DP, HDMI, hot-plug) once the guest OS driver initializes.

How it works

Three components are modified:

pkg/uefi — builds VfioIgdPkg open-source IGD Option ROM alongside OVMF.
VfioIgdPkg provides IgdAssignmentDxe: a DXE driver that reads etc/igd-opregion and etc/igd-bdsm-size from fw_cfg and sets PCI config registers ASLS (0xFC) and BDSM (0x5C / 0xC0 for Gen11+) required by the Intel display driver. Unlike the classic out-of-tree IgdAssignmentDxe patch, VfioIgdPkg handles 150+ device IDs from Sandy Bridge through Panther Lake and correctly handles the Gen11+ 64-bit BDSM register at 0xC0 (required for Raptor Lake and later). The built igd.rom is shipped in the EVE image at /usr/lib/xen/boot/igd.rom.

pkg/pillar/hypervisor (kvm.go) — detects Intel iGPU in the passthrough device list and:

  • Places iGPU at guest BDF 00:02.0 (pcie.0 addr=0x2) — required for VBIOS/GOP ROM initialization
  • Enables x-igd-opregion=on to pass the host OpRegion (including VBT) via fw_cfg — required for DP/HDMI connector detection and hot-plug
  • Moves USB root port from slot 0x2 to 0x1b to free slot 2 for the iGPU
  • Always loads the bundled igd.rom as the Option ROM; if a proprietary GOP ROM exists in /persist/gop/<devid>.rom, it is used instead (adds IntelGopDriver: UEFI framebuffer during firmware phase)

pkg/xen-tools (qemu-xen patch) — refactors vfio_probe_igd_bar4_quirk():

  • Moves GMCH emulation, etc/igd-bdsm-size fw_cfg write, and BDSM emulation to before the BDF/LPC bridge checks. On q35 the LPC check ("Sorry Q35") always fails so without this patch these registers are never set and the Windows driver fails with Code 43.
  • Emulates BDSM to 0 before the BDF check so OVMF's IgdAssignmentDxe idempotency guard (skip if BDSM ≠ 0) is not falsely triggered by the host physical address.
  • Fixes gen check: accept gen >= 0 instead of gen == 6 || gen == 8, which was blocking gen 9–12 devices.

Display paths

Configuration UEFI framebuffer (pre-OS) OS display (DP/HDMI/hot-plug)
Bundled igd.rom only (default) No Yes
+ Proprietary GOP ROM in /persist/gop/ Yes Yes

DP/HDMI and hot-plug are handled entirely by the guest OS i915/display driver via the OpRegion VBT and HPD interrupts. The UEFI phase only matters if you need a display before the OS boots.

Proprietary GOP ROMs (optional)

GOP ROMs are not included in EVE (licensing). For use cases requiring UEFI framebuffer, ROMs can be placed at /persist/gop/<devid>.rom (lowercase hex, no 0x prefix).

NOTE: this is for testing only!!! this PR will be updated to implement other way to store GOP ROMs

ROMs are available at https://github.com/LongQT-sea/intel-igpu-passthru/releases/

Device ID to ROM filename mapping
LongQT-sea filename Microarchitecture Example PCI device IDs
SNB_GOPv2_igd.rom Sandy Bridge 0102, 0106, 010a
IVB_GOPv3_igd.rom Ivy Bridge 0152, 0156, 015a, 0162, 0166
HSW_BDW_GOPv5_igd.rom Haswell, Broadwell 0402, 0406, 0412, 1602, 1606, 1612
SKL_CML_GOPv9_igd.rom Skylake, Comet Lake (U) 1902, 1906, 190b, 9b41, 9bca, 9bc8
CFL_CML_GOPv9.1_igd.rom Coffee Lake, Comet Lake (H) 3e90, 3e92, 3ea0, 9bc4, 9bc5
GLK_GOPv13_igd.rom Gemini Lake 3184, 3185
ICL_GOPv14_igd.rom Ice Lake 8a50, 8a51, 8a52, 8a56, 8a5a, 8a5c
RKL_TGL_ADL_RPL_GOPv17_igd.rom Rocket Lake, Tiger Lake, Alder Lake-P/S/U, Raptor Lake-P/U 4c8a, 4c8b, 9a40, 9a49, 4628, 46a0, 46a2, a780, a7a0, a7a1, a7a8
RKL_TGL_ADL_RPL_GOPv17.1_igd.rom same (newer GOP version) same as above
JSL_GOPv18_igd.rom Jasper Lake 4e51, 4e55, 4e57, 4e61
ADL-H_RPL-H_GOPv21_igd.rom Alder Lake-H, Raptor Lake-H 4626, 4638, a706, a720, a721
ADL-N_TWL_GOPv21_igd.rom Alder Lake-N 46d0, 46d1, 46d2
ARL_MTL_GOPv22_igd.rom Arrow Lake, Meteor Lake 7d45, 7d67, 7d51, 7d55
LNL_GOPv2X_igd.rom Lunar Lake 6420, 641b

Example for i5-1335UE (Raptor Lake-U, PCI device 0xa7a1):

cp ADL-H_RPL-H_GOPv21_igd.rom /persist/gop/a7a1.rom

How to test and validate this PR

  1. Build EVE with HV=kvm on an x86_64 host with an Intel iGPU (e.g. Intel Core i5-1335UE, device 00:02.0)
  2. Configure the iGPU as a passthrough device in an app instance
  3. Boot a Windows 11 or Linux VM
  4. Verify Intel display adapter appears without Code 43 (Windows) or i915 binds cleanly (Linux)
  5. Verify DP/HDMI output works and hot-plug events are detected in the guest
  6. Test with and without a GOP ROM in /persist/gop/
  7. Verify QEMU logs show IGD bdsm-size: entries confirming the fw_cfg write

Changelog notes

Add Intel iGPU passthrough support for KVM/UEFI guests. Enables Windows and Linux VMs to use Intel integrated graphics (Sandy Bridge through Raptor Lake and beyond) via VFIO passthrough, with full DP/HDMI/hot-plug support through the guest OS driver.

PR Backports

  • 16.0-stable: No
  • 14.5-stable: No
  • 13.4-stable: No

Checklist

  • I've provided a proper description

  • I've added the proper documentation

  • I've tested my PR on amd64 device

  • I've tested my PR on arm64 device

  • I've written the test verification instructions

  • I've set the proper labels to this PR

  • I've checked the boxes above, or I've provided a good reason why I didn't check them.

@github-actions github-actions bot requested a review from OhmSpectator March 18, 2026 22:46
@rucoder rucoder marked this pull request as draft March 18, 2026 22:49
@codecov
Copy link
Copy Markdown

codecov bot commented Mar 18, 2026

Codecov Report

✅ All modified and coverable lines are covered by tests.
✅ Project coverage is 29.87%. Comparing base (2281599) to head (1dabb63).
⚠️ Report is 376 commits behind head on master.

Additional details and impacted files
@@             Coverage Diff             @@
##           master    #5686       +/-   ##
===========================================
+ Coverage   19.52%   29.87%   +10.34%     
===========================================
  Files          19       18        -1     
  Lines        3021     2417      -604     
===========================================
+ Hits          590      722      +132     
+ Misses       2310     1549      -761     
- Partials      121      146       +25     

☔ View full report in Codecov by Sentry.
📢 Have feedback on the report? Share it here.

🚀 New features to boost your workflow:
  • ❄️ Test Analytics: Detect flaky tests, report on failures, and find test suite problems.

@rucoder rucoder force-pushed the rucoder/igpu-support branch from 056c12c to 54c2189 Compare March 19, 2026 16:25
@rucoder rucoder force-pushed the rucoder/igpu-support branch 17 times, most recently from d6cc0e9 to 1dabb63 Compare April 1, 2026 02:33
rucoder and others added 4 commits April 1, 2026 11:36
… ROM

Upgrade EDK2 from edk2-stable202408.01 to edk2-stable202508.01
(commit 3d244c3b364bd4e21261380662186d064659161c). This version added
MemDebugLogLib which VfioIgdPkg >= commit c7b537ef requires.

Build VfioIgdPkg (commit 348860da) as a standalone EFI Option ROM
(igd.rom) containing IgdAssignmentDxe. The DXE driver reads
etc/igd-opregion and etc/igd-bdsm-size from QEMU fw_cfg and sets
ASLS (0xFC) and BDSM (0x5C or 0xC0 for Gen11+) in the iGPU PCI
config space, enabling i915 to initialize the device on q35/UEFI.

Regenerate edk2 patches for the new EDK2 base. All four existing
patches still apply:
  0000: Xen hypervisor spoofing in XenPlatformPei
  0001: EveBootOrderLib addition
  0002: EVE OS logo replacement
  0003: EveBootOrderLib fw_cfg boot order support

Signed-off-by: Mikhail Malyshev <mike.malyshev@gmail.com>
When an Intel iGPU (vendor 0x8086, class 0x03xx) is in the vfio-pci
passthrough list:

- Place the iGPU at guest BDF 00:02.0 (required for VBIOS/GOP ROM)
- Enable x-igd-opregion=on for OpRegion/VBT passthrough via fw_cfg
- Load igd.rom as the Option ROM (IgdAssignmentDxe sets ASLS/BDSM)
- Move USB root port from slot 0x2 to 0x1b to free the iGPU slot
- Support optional proprietary GOP ROMs for UEFI framebuffer

Update eve-uefi reference to pick up edk2-stable202508.01 and igd.rom.

Signed-off-by: Mikhail Malyshev <mike.malyshev@gmail.com>
Replace the old Revert^2 stolen-memory patch with four targeted patches
for QEMU's hw/vfio/igd.c enabling Intel iGPU passthrough on q35/UEFI:

Patch 08 — backport upstream igd_gen() with Gen7-Gen12 device ID
detection.  The old function returned 8 for all unrecognised IDs,
making generation-specific checks (BDSM offset, GMS encoding)
ineffective on Gen9+ hardware.

Patch 09 — restructure vfio_probe_igd_bar4_quirk() for q35/UEFI:
  - Move GMCH/BDSM emulation and etc/igd-bdsm-size fw_cfg write before
    the BDF/LPC bridge checks (q35 "Sorry Q35" exits early without it)
  - Emulate BDSM at 0xC0 (64-bit) for Gen11+, 0x5C (32-bit) for older
  - Preserve GMS in emulated GMCH (guest driver needs stolen memory size)
  - Clear stale GTT entries from host POST to prevent IOMMU faults
  - Fix GMS encoding for Gen9+ Atom SKUs (0xf0-0xff, 4 MB granularity)

Patch 10 — add BAR0 BDSM MMIO mirror quirk (backported from upstream).
The GPU reads BDSM through BAR0 at offset 0x1080C0 as well as PCI
config space; without the mirror the MMIO read returns the host PA
while PCI config returns the emulated guest PA, crashing the driver.

Patch 11 — temporary diagnostic logging for BDSM/GMCH/GTT/BAR0 mirror.

Also ship igd.rom in xen-tools (where QEMU runs on the host rootfs)
and update the eve-uefi reference.

Co-authored-by: Sergio Santos <sergioliveirasantos@gmail.com>
Signed-off-by: Mikhail Malyshev <mike.malyshev@gmail.com>
Explain how Intel integrated GPU passthrough works in EVE OS: the
OpRegion (ASLS) and stolen memory (BDSM) firmware requirements, why
SeaBIOS/i440fx works via the legacy VBIOS path, why q35/UEFI fails
without special handling, and how VfioIgdPkg's IgdAssignmentDxe EFI
Option ROM solves it.

Covers the four QEMU patches (igd_gen backport, main rework, BAR0
BDSM mirror, diagnostic logging), supported GPU generations (Gen6
through Gen12+), what works and what does not, and a step-by-step
guide for updating EVE when Intel releases a new iGPU generation.

Signed-off-by: Mikhail Malyshev <mike.malyshev@gmail.com>
@rucoder rucoder force-pushed the rucoder/igpu-support branch from 1dabb63 to afcda61 Compare April 1, 2026 11:36
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Labels

None yet

Projects

None yet

Development

Successfully merging this pull request may close these issues.

1 participant